package com.whli.jee.common.util;

import com.whli.jee.common.cache.RedisConfig;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Map;

/**
 * @Desc Redis客户端操作工具Jedis类
 * @Author whli
 * @Version 1.0
 * @Date 2018/6/2 12:51
 */
public class JedisUtils {
    private static JedisPool jedisPool;
    //成功返回标识
    private static final String SUCCESS_STATUS_OK = "OK";
    private static final Long SUCCESS_STATUS_LONG = 1L;

    private JedisUtils(){}

    /**
     * @Desc 获取单例JedisPool
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:14
     * @Params []
     * @Return redis.clients.jedis.JedisPool
     */
    public static JedisPool getJedisPool(){
        if (null == jedisPool){
            synchronized (JedisUtils.class){
                try {
                    if (null == jedisPool){
                        JedisPoolConfig config = new JedisPoolConfig();
                        config.setMaxIdle(RedisConfig.maxIdle);
                        config.setMaxWaitMillis(RedisConfig.maxWaitMillis);
                        config.setMaxTotal(RedisConfig.total);
                        if (StringUtils.isNotBlank(RedisConfig.password)){
                            jedisPool = new JedisPool(config,RedisConfig.host,RedisConfig.port,RedisConfig.timeout,RedisConfig.password);
                        } else {
                            jedisPool = new JedisPool(config,RedisConfig.host,RedisConfig.port,RedisConfig.timeout);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if (jedisPool != null){
                        jedisPool.close();
                    }
                }
            }
        }
        return jedisPool;
    }

    /**
     * 同步获取Jedis实例
     *
     * @return Jedis
     */
    public static Jedis getJedis() {

        Jedis jedis = null;
        try {
            jedis = getJedisPool().getResource();
        } catch (Exception e) {
            returnBrokenResource(jedis);
        }

        return jedis;
    }

    /**
     * 释放Jedis资源
     *
     * @param jedis
     */
    @SuppressWarnings("deprecation")
    public static void returnResource(final Jedis jedis) {
        if (jedis != null && jedisPool != null) {
            jedisPool.returnResource(jedis);
        }
    }

    /**
     * 释放Jedis坏的资源
     * @param jedis
     */
    @SuppressWarnings("deprecation")
    public static void returnBrokenResource(final Jedis jedis) {
        if (jedis != null && jedisPool != null) {
            jedisPool.returnBrokenResource(jedis);
        }
    }

    /**
     * @Desc 存储key-value样式的数据
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:27
     * @Params [key 键, value 值]
     * @Return void
     */
    public static boolean set(String key,String value){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        
        try {
            String statusCode = jedis.set(key,value);
            if (SUCCESS_STATUS_OK.equals(statusCode)){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * @Desc 存储key-value样式的数据,并设定过期时间
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:27
     * @Params [key 键, value 值]
     * @Return void
     */
    public static boolean setEx(String key,String value,int seconds){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try {

            seconds = seconds <= 0 ? RedisConfig.defaultExpire : seconds;
            String statusCode = jedis.setex(key,seconds,value);
            if (SUCCESS_STATUS_OK.equals(statusCode)){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * @Desc 根据key获取redis里key-value样式的值
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:32
     * @Params [key]
     * @Return java.lang.String
     */
    public static String get(String key){
        Jedis jedis = getJedis();
        if (jedis == null){
            return null;
        }
        String value = null;
        try{
            value = jedis.get(key);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * @Desc 判断key是否存在
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/3 9:59
     * @Params [key]
     * @Return boolean
     */
    public static boolean exists(String key){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try{
            if(StringUtils.isNotBlank(key)){
                return jedis.exists(key);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * @Desc 存储key:{filed:value}样式的数据
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:32
     * @Params [key, filed, value]
     * @Return void
     */
    public static boolean hSet(String key,String field,String value){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try {
            Long statusCode = jedis.hset(key, field, value);
            if (SUCCESS_STATUS_LONG.compareTo(statusCode) == 0){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * @Desc 存储key:{filed:value}样式的数据
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:32
     * @Params [key, filed, value]
     * @Return void
     */
    public static boolean hSet(String key,String field,String value,int seconds){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try {
            Long statusCode = jedis.hset(key,field,value);
            seconds = seconds <= 0 ? RedisConfig.defaultExpire : seconds;
            expire(key,seconds);
            if (SUCCESS_STATUS_LONG.compareTo(statusCode) == 0){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * @Desc 存储key:Map样式的数据
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:32
     * @Params [key, filed, value]
     * @Return void
     */
    public static boolean hMSet(String key, Map<String,String> params){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }

        try {
            String result = jedis.hmset(key, params);
            if (SUCCESS_STATUS_OK.equals(result)){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }

        return false;
    }

    /**
     * @Desc 存储key:Map样式的数据
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:32
     * @Params [key, filed, value]
     * @Return void
     */
    public static boolean hMSet(String key, Map<String,String> params,int seconds){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }

        try {
            String result = jedis.hmset(key, params);
            seconds = seconds <= 0 ? RedisConfig.defaultExpire : seconds;
            expire(key,seconds);
            if (SUCCESS_STATUS_OK.equals(result)){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }

        return false;
    }

    /**
     * @Desc 根据key,filed获取redis里key:{field:value}样式的值
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 14:35
     * @Params [key, filed]
     * @Return java.lang.String
     */
    public static String hGet(String key,String field){
        Jedis jedis = getJedis();
        if (jedis == null){
            return null;
        }
        String value = null;
        try {
            value = jedis.hget(key, field);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * @Desc 根据删除值
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/2 23:40
     * @Params [key]
     * @Return void
     */
    public static boolean delete(String... key){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try {
           Long statusCode = jedis.del(key);
            if (SUCCESS_STATUS_LONG.compareTo(statusCode) == 0){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * 批量删除Map
     * @param key
     * @param fields
     * @return
     */
    public static boolean hDelete(String key, String... fields){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try {
            Long statusCode = jedis.hdel(key,fields);
            if (SUCCESS_STATUS_LONG.compareTo(statusCode) == 0){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }

    /**
     * @Desc 设置key过期时间
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/3 0:49
     * @Params [key, seconds]
     * @Return boolean
     */
    public static boolean expireDefault(String key){
        return expire(key,RedisConfig.defaultExpire);
    }

    /**
     * @Desc 设置key过期时间
     * @Author whli
     * @Version 1.0
     * @Date 2018/6/3 0:49
     * @Params [key, seconds]
     * @Return boolean
     */
    public static boolean expire(String key,int seconds){
        Jedis jedis = getJedis();
        if (jedis == null){
            return false;
        }
        try {
            Long statusCode = jedis.expire(key,seconds);
            if (SUCCESS_STATUS_LONG.compareTo(statusCode) == 0){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return false;
    }
}
